package com.sq.partner.manager.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import com.sq.partner.manager.dao.*;
import com.sq.partner.manager.mybatis.model.*;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;
import org.springframework.web.multipart.MultipartFile;

import com.sq.partner.manager.common.Config;
import com.sq.partner.manager.common.Constants;
import com.sq.partner.manager.common.DictCache;
import com.sq.partner.manager.common.Result;
import com.sq.partner.manager.common.exception.AppException;
import com.sq.partner.manager.service.IGatewayChannelInfoConfigService;
import com.sq.partner.manager.service.IGatewayClearCacheManager;
import com.sq.partner.manager.service.IGatewayConfigService;
import com.sq.partner.manager.service.INlifePlanConfigService;
import com.sq.partner.manager.service.ITradInsuPlanGroupService;
import com.sq.partner.manager.util.DocToHtml;
import com.sq.partner.manager.util.LogUtil;
import com.sq.partner.manager.util.Page;
import com.sq.partner.manager.util.StrUtil;
import com.sq.partner.manager.util.WebServiceUtil;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

@Service
public class NlifePlanConfigServiceImpl implements INlifePlanConfigService {

	private static Logger logger = LogUtil.getLog(NlifePlanConfigServiceImpl.class);
	
	@Resource
	private INlifePlanDao nlifePlanDao;

	@Resource
	private INlifeRiskDao nlifeRiskDao;

	@Resource
	private INlifeCoreRiskDao iNlifeCoreRiskDao;
	
	@Resource
	private INlifeProdDao nlifeProdDao;

	@Resource
	private INlifeCoreProdDao nlifeCoreProdDao;
	
	@Resource
	private ITradInsuPlanGroupService insuPlanGroupService;
	
	@Resource
	ITradPlanGroupDao planGroupDao;
	
	@Resource
	private IGatewayChannelInfoConfigDao channelInfoDao;
	
	@Resource
	ICoreDeptDao deptDao;
	
	@Resource
	private IGatewayAgentInfoRelaDao agentInfoRelaDao;
	
	@Resource
	private IGatewayAgentInfoMtDao agentInfoDao;
	
	@Resource
	private IGatewayChannelInfoConfigService channelInfoConfigService;
	
	@Resource
	private IGatewayClearCacheManager gatewayClearCacheManager;
	
	@Resource
	private TradSmsTemplateDao tradSmsTemplateDao;
	
	@Resource
	private CoinFeeConfigDao coinFeeConfigDao;
	@Resource
	private ICoreDeptDao coreDeptDao;
	@Resource
	private  IGatewayConfigService  gatewayConfigService;
	@Override
	public Page<GatewayChannelInfo> queryChannelInfoPageByCriteria(
			Page<GatewayChannelInfo> page) throws Exception {
		page = channelInfoDao.getListByDept(page);
		
		return page;
	}
	
	@Override
	public Page<Map<String,Object>> queryNlifePlanPageByCriteria(Page<Map<String,Object>> page)
			throws Exception {
		page = nlifePlanDao.queryPageByCriteria(page);
		
		return page;
	}

	@Override
	public Result delNlifePlan(NlifePlan nlifePlan,HttpSession session) throws Exception {
		nlifePlan = nlifePlanDao.queryById(nlifePlan.getPlanNo());
		GatewayUser user=(GatewayUser) session.getAttribute(Constants.SESSION_USER);
		String deptCode=user.getDepartmentStr();
		if(!"'00'".equals(deptCode)){
			GatewayChannelInfo info=new GatewayChannelInfo();
			info.setChannelCode(nlifePlan.getPartnerNo());
			info=channelInfoDao.queryByChannelInfo(info);
			if("00".equals(info.getDeptCode())){
				return Result.error("删除失败，分公司不允许删除总公司方案");
			}
		}
		String status = nlifePlan.getState();
		if(1 == Integer.parseInt(status)){
			return Result.error("该方案状态为有效，不能删除");
		}else{
			String agentType = nlifePlan.getAgentType();
			//1、合作伙伴代理3、个人代理4、总对总代理
			if("3".equals(agentType)||"4".equals(agentType)){
				//根据方案号删除方案下面配置的代理信息
				agentInfoRelaDao.delTradAgentInfoRelaByPlanNo(nlifePlan.getPlanNo());
			}
			boolean flag = nlifePlanDao.delById(nlifePlan.getPlanNo());
			//清除缓存
			channelInfoConfigService.clearAllCacheByChannelCode(nlifePlan.getPartnerNo());
		
			if(flag){
				//删除方案组关联
				insuPlanGroupService.deleteTradInsuPlanGroupByInsuPlanNo(nlifePlan.getPlanNo());
				return Result.success("删除成功");
			}else{
				return Result.error("删除失败");
			}
		}
	}

	@Override
	public void toAddNlifePlan(ModelMap modelMap) throws Exception {
		//页面初始化加载字典表数据
		loadDictDataBeforeAddOrEdit(modelMap);
	}
	
	@Override
	public void toEditNlifePlan(ModelMap modelMap,String planNo) throws Exception {
		//页面初始化加载字典表数据
		loadDictDataBeforeAddOrEdit(modelMap);
		
		modelMap.put("planNo", planNo);
	}

	@Override
	public void toCopyAddNlifePlan(ModelMap modelMap,String planNo) throws Exception {
		//页面初始化加载字典表数据
		loadDictDataBeforeAddOrEdit(modelMap);
		modelMap.put("oldPlanNo", planNo);
	}
	
	/**
	 * 新增 或 编辑 页面跳转前 往modelMap中存放字典表数据
	 * @param modelMap
	 * @throws Exception
	 */
	private void loadDictDataBeforeAddOrEdit(ModelMap modelMap) throws Exception{
		//争议处理方式
		List<DictDto> dicputeTypes=DictCache.getDict(Constants.DICT_DICPUTE_TYPE);
		//仲裁委员会名称
		List<DictDto> arbitrationDepts=DictCache.getDict(Constants.DICT_ARBITRATION_DEPT);
		//回执类型
		List<DictDto> receiptTypeLs = DictCache.getDict(Constants.DICT_RECEIPT_TYPE_OPTIONS);
		//初始化方案销售类型
		List<DictDto> agentTypes = DictCache.getDict(Constants.DICT_AGENT_TYPE);
		//联合出单方案
		List<DictDto> unionTypes = DictCache.getDict(Constants.DICT_UNION_TYPE);
		//电子保单文件方式
		List<DictDto> fileTypes = DictCache.getDict(Constants.DICT_FILE_TYPE);
		//车辆类型信息
		List<DictDto> carNatureList = DictCache.getDict("VHL_NLIFE_CAR_MANAGER");//使用的字典待确定
		//两位和四位机构代码
		List<CoreDept> provenceDeptList = coreDeptDao.queryProvenceAndNextLevelDept();
		//发票购方,1,投保人2,被保人3,接口传入
		List<DictDto> payEinvoices = DictCache.getDict(Constants.DICT_PAY_EINVOICE);
		//分期类型
		List<DictDto> paymentTypeLs = DictCache.getDict(Constants.DICT_PAYMENT_TYPE_OPTIONS);
		/**方案号生成规则*/
		GatewayConfig gatewayConfig=gatewayConfigService.queryConfigByName(Constants.PTN_ENV);
		//业务来源1
		List<DictDto> businessNature1List = DictCache.getDict(Constants.DICT_BUSINESS_NATURE_1);
		//业务来源2
		List<DictDto> businessNature2List = DictCache.getDict(Constants.DICT_BUSINESS_NATURE_2);
		//业务来源3
		List<DictDto> businessNature3List = DictCache.getDict(Constants.DICT_BUSINESS_NATURE_3);
		//绿色产业1级
		List<DictDto> greenIndustryFirstList = DictCache.getDict(Constants.DICT_GREEN_INDUSTRY_FRIST);
		//绿色产业2级
		List<DictDto> greenIndustrySecondList = DictCache.getDict(Constants.DICT_GREEN_INDUSTRY_SECOND);
		//统信渠道1级
		List<DictDto> txChannel1stList = DictCache.getDict(Constants.TX_CHANNEL_1ST);
		//统信渠道2级
		List<DictDto> txChannel2ndList = DictCache.getDict(Constants.TX_CHANNEL_2ND);
		//统括标志
		List<DictDto> tkFlagList = DictCache.getDict(Constants.TK_FLAG);
		/**只有st显示不分大小写*/
		if(gatewayConfig!=null&&"ST".equalsIgnoreCase(gatewayConfig.getConfigValue())){
			modelMap.put("ptnEnv", "display:''");
		}else{
			modelMap.put("ptnEnv", "display:none");
		}
		modelMap.put("receiptTypeLs", receiptTypeLs);
		modelMap.put("payEinvoices", payEinvoices);
		modelMap.put("dicputeTypes", dicputeTypes);
		modelMap.put("arbitrationDepts", arbitrationDepts);
		modelMap.put("unionTypes", unionTypes);
		modelMap.put("agentTypes", agentTypes);
		modelMap.put("fileTypes", fileTypes);
		modelMap.put("paymentTypeLs", paymentTypeLs);
		modelMap.put("carNatureList", carNatureList);
		modelMap.put("provenceDeptList", provenceDeptList);
		modelMap.put("businessNature1List", businessNature1List);
		modelMap.put("businessNature2List", businessNature2List);
		modelMap.put("businessNature3List", businessNature3List);
		modelMap.put("greenIndustryFirstList", greenIndustryFirstList);
		modelMap.put("greenIndustrySecondList", greenIndustrySecondList);
		modelMap.put("txChannel1stList", txChannel1stList);
		modelMap.put("txChannel2ndList", txChannel2ndList);
		modelMap.put("tkFlagList", tkFlagList);
	}

	@Override
	public Map<String, Object> loadNlifePlan(String planNo) throws Exception {
		Map<String,Object> map = new HashMap<String, Object>();

		NlifePlan nlifePlan = nlifePlanDao.queryById(planNo);
		NlifeProd nlifeProd = nlifeProdDao.queryProdInfoById(nlifePlan.getProdCode());
		NlifeCoreProd nlifeCoreProd = nlifeCoreProdDao.queryById(nlifeProd.getCoreProdCode());
		String idStr = nlifePlan.getSelAccessory();
		String[] ids=null;
		if(idStr!=null){
			ids=idStr.split(",");
		}
		map.put("ids", ids);
		map.put("nlifePlan", nlifePlan);
		map.put("nlifeProd", nlifeProd);
		map.put("nlifeCoreProd", nlifeCoreProd);

		String agentType= nlifePlan.getAgentType();
		//3 个人  4总对总
		if("3".equals(agentType) || "4".equals(agentType) ||"5".equals(agentType)||"7".equals(agentType)){
			
			List<Map> agentInfoList = agentInfoRelaDao.queryAgentInfoByInsuPlanNo(planNo);
			map.put("agentInfoList", agentInfoList);
		}
		GatewayChannelInfo info=channelInfoConfigService.queryChannelInfoByChannelCode(nlifePlan.getPartnerNo());
		map.put("thirdPlan", info.getIsThirdPlan());
		map.put("planChannelInfo", info);
		return map;
	}

	@Override
	public Page<NlifeProd> queryNlifeProdPageByCriteria(Page<NlifeProd> page)
			throws Exception {
		page = nlifeProdDao.queryPageByCriteria(page);
		return page;
	}

	@Override
	public Page<CoreDept> queryDeptPageByCriteria(Page<CoreDept> page)
			throws Exception {
		String partnerNo = page.getObj()==null?"":page.getObj().toString();
		page = deptDao.queryCoreDeptPage(page,partnerNo);
		return page;
	}

	@Override
	public List<DictDto> loadSubCascadeList(DictDto dict)
			throws Exception {
		String codeType = dict.getCodeType();
		String parentCode = dict.getParentCode();
		
		List<DictDto> list = new ArrayList<DictDto>();
		if (StrUtil.isNotEmpty(codeType) && StrUtil.isNotEmpty(parentCode)) {
			List<DictDto> subDataList = DictCache.getDictDataByParentCode(codeType, parentCode);
			if("new_business_source".equals(codeType)){
				subDataList = DictCache.remakeNewBussinessSource(subDataList);
			}
			//复制list
			list.addAll(subDataList);
			//倒序
			Collections.reverse(list);
			DictDto dd = new DictDto();
			dd.setCode("");
			dd.setCodeName("----请选择----");
			list.add(dd);
			//倒序
			Collections.reverse(list);
			return list;
		}else{
			DictDto dd = new DictDto();
			dd.setCode("");
			if(Constants.DICT_CHANNEL_TYPE.equals(codeType)){
				dd.setCodeName("----请选择归属渠道----");
			}else if(Constants.DICT_NEW_BUSINESS_SOURCE.equals(codeType)){
				dd.setCodeName("----请选择渠道类型----");
			}
			list.add(dd);
		}
		return list;
	}

	@Override
	public Result querySauserAndTeamInfo(String COMCODE)
			throws Exception {
		String url = Config.getProp("SALES_WEBSERVICE_URL");
		String method = Config.getProp("querySauserAndTeamInfo_METHOD");
		String namespace = Config.getProp("querySauserAndTeamInfo_NAMESPACE");
		
		//拼接请求报文
		String reqXml = 
				"<?xml version=\"1.0\" encoding=\"GBK\"?>" +
					"<XML>" +
						"<USER>" +
							//归属机构代码(必传)
							"<COMCODE>" + COMCODE + "</COMCODE>" +
							//业务员名称
							"<USERNAME></USERNAME>" +
							//业务员代码(校验使用)
							"<USERCODE></USERCODE>" +
							//渠道名称
							"<CHANNELNAME></CHANNELNAME>" +
							//中介代码
							"<AGENTCODE></AGENTCODE>" +
						"</USER>" +
					"</XML>";
		logger.info("查询业务员-团队信息--》请求报文:"+reqXml);
		
		String respXml = "";
		try{
		    //调用销管接口
			respXml = WebServiceUtil.call(reqXml, url, method, namespace);
			logger.info("查询业务员-团队信息--》返回报文:"+respXml);
		}catch(Exception e){
			logger.info("调用销管接口获取数据异常:",e);
			throw new AppException("调用销管接口获取数据异常:" , e);
		}
		
		// 解析响应报文
		Document document=null;
		try {
			document = DocumentHelper.parseText(respXml);
		} catch (DocumentException e) {
			logger.info("解析销管返回报文异常",e);
			throw new AppException("解析销管返回报文异常:" , e);
		}
		Element root  = document.getRootElement();
		Element RETURN = root.element("RETURN");
		String RETURNCODE = RETURN.elementTextTrim("RETURNCODE");
		Element RETURNMSG = RETURN.element("RETURNMSG");
		
		//存放业务员和团队信息的List
		List<Map<String,Object>> TEAMUSERList = new ArrayList<Map<String,Object>>();
		if("0000".equals(RETURNCODE)){//成功
			List<Element> TEAMUSER_elementList = RETURNMSG.elements("TEAM-USER");
			for (Element TEAMUSER_element : TEAMUSER_elementList) {
				String USERCODE = TEAMUSER_element.elementTextTrim("USERCODE");
				String USERNAME = TEAMUSER_element.elementTextTrim("USERNAME");
				String PHONENO = TEAMUSER_element.elementTextTrim("PHONENO");
				
				Map<String,Object> TEAMUSER = new HashMap<String, Object>();
				TEAMUSER.put("USERCODE", USERCODE);//业务员代码
				TEAMUSER.put("USERNAME", USERNAME);//业务员名称
				TEAMUSER.put("PHONENO", PHONENO);//电话
				
				List<Element> TEAM_elementList = TEAMUSER_element.elements("TEAM");
				//存放每个业务员对应团队信息的List
				List<Map<String,String>> TEAMList = new ArrayList<Map<String,String>>();
				for (Element TEAM_element : TEAM_elementList) {
					String TEAMCODE = TEAM_element.elementTextTrim("TEAMCODE");
					String TEAMNAME = TEAM_element.elementTextTrim("TEAMNAME");
					String CHANNELNAME = TEAM_element.elementTextTrim("CHANNELNAME");
					Map<String,String> TEAM = new HashMap<String, String>();
					TEAM.put("TEAMCODE",TEAMCODE);//团队代码
					TEAM.put("TEAMNAME", TEAMNAME);//团队名称
					TEAM.put("CHANNELNAME",CHANNELNAME);
					TEAMList.add(TEAM);
				}
				TEAMUSER.put("TEAMList", TEAMList);
				TEAMUSERList.add(TEAMUSER);
			}
		
		}else{
			throw new AppException("调用销管接口获取数据失败:RETURNCODE:" + RETURNCODE +
					"，RETURNMSG:" + RETURNMSG.getTextTrim());
		} 
		return Result.success(TEAMUSERList);
	}

	@Override
	public Result queryAgentAndAgreeInfo(String COMCODE, String TEAMCODE,
			String BUSINESSSOURCE, String CHANNELNAME, String PRODCODE)
			throws Exception {
		String url = Config.getProp("SALES_WEBSERVICE_URL");
		String method = Config.getProp("queryAgentAndAgreeInfo_METHOD");
		String namespace = Config.getProp("queryAgentAndAgreeInfo_NAMESPACE");
		
		//拼接请求报文
		String reqXml = 
				"<?xml version=\"1.0\" encoding=\"GBK\"?>" +
					"<XML>" +
						"<AGENT>" +
							//归属机构代码(必传)
							"<COMCODE>"+ COMCODE +"</COMCODE>" +
							//团队代码(必传)
							"<TEAMCODE>"+ TEAMCODE +"</TEAMCODE>" +
							//业务来源(必传)
							"<BUSINESSSOURCE>"+ BUSINESSSOURCE +"</BUSINESSSOURCE>" +
							//渠道名称(必传)
							"<CHANNELNAME>"+ CHANNELNAME +"</CHANNELNAME>" +
							//产品代码(必传)
							"<PRODCODE>"+ PRODCODE +"</PRODCODE>" +
							//中介代码(校验使用)
							"<AGENTCODE></AGENTCODE>" +
							//业务员名称
							"<USERCODE></USERCODE>" +
						"</AGENT>" +
					"</XML>";
		logger.info("查询中介-协议信息--》请求报文:"+reqXml);
		
		String respXml = "";
		try{
		    //调用销管接口
			respXml = WebServiceUtil.call(reqXml, url, method, namespace);
			logger.info("查询中介-协议信息--》返回报文:"+respXml);
		}catch(Exception e){
			logger.info("调用销管接口获取数据异常",e);
			throw new AppException("调用销管接口获取数据异常:" , e);
		}
		
		// 解析响应报文
		Document document=null;
		try {
			document = DocumentHelper.parseText(respXml);
		} catch (DocumentException e) {
			logger.info("解析销管返回报文异常",e);
			throw new AppException("解析销管返回报文异常:" , e);
		}
		Element root  = document.getRootElement();
		Element RETURN = root.element("RETURN");
		String RETURNCODE = RETURN.elementTextTrim("RETURNCODE");
		Element RETURNMSG = RETURN.element("RETURNMSG");
		
		//存放代理、协议信息的List
		List<Map<String,Object>> AGENTAGREEMENTList = new ArrayList<Map<String,Object>>();
		if("0000".equals(RETURNCODE)){//成功
			List<Element> AGENTAGREEMENT_elementList = RETURNMSG.elements("AGENT-AGREEMENT");
			for (Element AGENTAGREEMENT_element : AGENTAGREEMENT_elementList) {
				String AGENTCODE = AGENTAGREEMENT_element.elementTextTrim("AGENTCODE");
				String AGENTNAME = AGENTAGREEMENT_element.elementTextTrim("AGENTNAME");
				String AGREEMENTNO = AGENTAGREEMENT_element.elementTextTrim("AGREEMENTNO");
				//请求时只有一个PRODCODE值，RISKDETAIL节点则只有一个
				List<Element> RISKDETAIL_elementList = AGENTAGREEMENT_element.elements("RISKDETAIL");
				Element RISKDETAIL_element = RISKDETAIL_elementList.get(0);
				String FEEMAXRATE  = RISKDETAIL_element.elementTextTrim("FEEMAXRATE");
				String FEEMINRATE  = RISKDETAIL_element.elementTextTrim("FEEMINRATE");
				double feeMaxRate = 0;
				try{
					feeMaxRate = Double.parseDouble(FEEMAXRATE) * 0.01;
				}catch(Exception e){
					feeMaxRate = 1;
					logger.info(e);
				}
				FEEMAXRATE = Double.toString(feeMaxRate);
				
				double feeMinRate = 0;
				try{
					feeMinRate = Double.parseDouble(FEEMINRATE) * 0.01;
				}catch(Exception e){
					feeMinRate = 0;
					logger.info(e);
				}
				FEEMINRATE = Double.toString(feeMinRate);
				
				Map<String,Object> AGENTAGREEMENT = new HashMap<String, Object>();
				AGENTAGREEMENT.put("AGENTCODE", AGENTCODE);//代理人代码
				AGENTAGREEMENT.put("AGREEMENTNO", AGREEMENTNO);//协议代码
				AGENTAGREEMENT.put("AGENTNAME", AGENTNAME);//代理名称
				AGENTAGREEMENT.put("FEEMAXRATE", FEEMAXRATE);//手续费比例上限
				AGENTAGREEMENT.put("FEEMINRATE", FEEMINRATE);//手续费比例下限
				AGENTAGREEMENTList.add(AGENTAGREEMENT);
			}
		}else{
			throw new AppException("调用销管接口获取数据失败:" + RETURNMSG.getTextTrim());
		} 
		return Result.success(AGENTAGREEMENTList);
	}

	@Override
	public Result queryServiceNo(String COMCODE, String BUSINESSSOURCE,
			String CHANNELNAME, String USERCODE, String AGENTCODE)
			throws Exception {
		String url = Config.getProp("SALES_WEBSERVICE_URL");
		String method = Config.getProp("queryServiceNo_METHOD");
		String namespace = Config.getProp("queryServiceNo_NAMESPACE");
		
		//拼接请求报文
		String reqXml = 
				"<?xml version=\"1.0\" encoding=\"GBK\"?>" +
						"<XML>" +
							"<AGENT>" +
								//归属机构代码(必传)
								"<COMCODE>"+ COMCODE +"</COMCODE>" +
								//业务来源(必传)
								"<BUSINESSSOURCE>"+ BUSINESSSOURCE +"</BUSINESSSOURCE>" +
								//渠道名称(必传)
								"<CHANNELNAME>"+ CHANNELNAME +"</CHANNELNAME>" +
								//业务员代码(必传)
								"<USERCODE>"+ USERCODE +"</USERCODE>" +
								//中介代码(必传)
								"<AGENTCODE>"+ AGENTCODE +"</AGENTCODE >" +
								//服务代码
								"<SERVICENO></SERVICENO>" +
								//合作机构名称
								"<SERVICENAME></SERVICENAME>" +
							"</AGENT>" +
						"</XML>";
		logger.info("查询服务代码信息--》请求报文:"+reqXml);
		
		String respXml = "";
		try{
		    //调用销管接口
			respXml = WebServiceUtil.call(reqXml, url, method, namespace);
			logger.info("查询服务代码信息--》返回报文:"+respXml);
		}catch(Exception e){
			logger.info("调用销管接口获取数据异常",e);
			throw new AppException("调用销管接口获取数据异常:" , e);
		}
		
		// 解析响应报文
		Document document=null;
		try {
			document = DocumentHelper.parseText(respXml);
		} catch (DocumentException e) {
			logger.info("解析销管返回报文异常",e);
			throw new AppException("解析销管返回报文异常:" , e);
		}
		Element root  = document.getRootElement();
		Element RETURN = root.element("RETURN");
		String RETURNCODE = RETURN.elementTextTrim("RETURNCODE");
		Element RETURNMSG = RETURN.element("RETURNMSG");
		
		//存放服务代码的List
		List<Map<String,Object>> SERVICENOSList = new ArrayList<Map<String,Object>>();
		if("0000".equals(RETURNCODE)){//成功
			List<Element> SERVICENOS_elementList = RETURNMSG.elements("SERVICENOS");
			for (Element SERVICENOS_element : SERVICENOS_elementList) {
				String SERVICENO = SERVICENOS_element.elementTextTrim("SERVICENO");
				String SERVICENAME = SERVICENOS_element.elementTextTrim("SERVICENAME");
				
				Map<String,Object> SERVICENOS = new HashMap<String, Object>();
				SERVICENOS.put("SERVICENO", SERVICENO);//服务代码
				SERVICENOS.put("SERVICENAME", SERVICENAME);//服务名称
				
				SERVICENOSList.add(SERVICENOS);
			}
		}else{
			throw new AppException("调用销管接口获取数据失败:RETURNCODE:" + RETURNCODE +
					"，RETURNMSG:" + RETURNMSG.getTextTrim());
		} 
		return Result.success(SERVICENOSList);
	}

	@Override
	public Result addNlifePlan(NlifePlan nlifePlan,NlifeProd nlifeProd,String channelFlag) throws Exception {
		//产品销售类型为代理类型
		String state = nlifePlan.getState();
		String agentType = nlifePlan.getAgentType();
		if("3".equals(agentType) || "4".equals(agentType)){
			if("1".equals(state)&&!"1".equals(channelFlag)){
				return Result.error("方案添加时，产品销售类型为代理类型则方案不能置为有效状态");
			}
		}
		String planNo="";
		/**根据是否上线产品生成方案号*/
		if(nlifePlan.getIsProprod()){
			planNo= nlifePlanDao.queryNextPlanNo("CIC"+nlifeProd.getCoreProdCode());
		}else{
			planNo= nlifePlanDao.queryNextPlanNo("ZHA");
		}
		nlifePlan.setPlanNo(planNo);
		boolean flag = nlifePlanDao.add(nlifePlan);
		//清除缓存
		//gatewayClearCacheManager.clearNlifeCacheInfoManager();
//		channelInfoConfigService.clearAllCacheByChannelCode(nlifePlan.getPartnerNo());
		
		if(flag){
			logger.info("==========================添加投保方案成功=============================");

			//根据方案对应的产品的产品类型，查询相应方案组信息,将该方案和方案组信息维护到方案与方案组关联表
			TradPlanGroup planGroup = new TradPlanGroup();
			planGroup.setProdType(nlifeProd.getProdType());
			planGroup = planGroupDao.queryTradPlanGroupID(planGroup);
			
			//维护方案与方案组关联表
			if(planGroup != null){
				TradInsuPlanGroup group = new TradInsuPlanGroup();
				group.setInsuPlanNumber(nlifePlan.getPlanNo());
				group.setPlanGroupId(StrUtil.getVal(planGroup.getGroupId()));
				group.setRequired("0");
				boolean f = insuPlanGroupService.addTradInsuPlanGroup(group);
				
				if(!f){return Result.error("维护方案与方案组关联出错");}
			}
			Map<String,String> returnMap = new HashMap<String,String>();
			returnMap.put("planNo", planNo);
			returnMap.put("agentType", nlifePlan.getAgentType());
			returnMap.put("agentFeeConfig", nlifePlan.getAgentFeeConfig());
			return Result.successAndData("添加成功",returnMap);
		}else{
			return Result.error("添加失败");
		}
	}

	@Override
	public Result copyAddNlifePlan(String oldPlanNo,String oldPartnerNo, String oldAgentType, NlifePlan nlifePlan, NlifeProd nlifeProd,String channelFlag)
			throws Exception {
		
		boolean isCopyTradAgentInfoRela = false;
		
		//产品销售类型为代理类型
		String state = nlifePlan.getState();
		String partnerNo = nlifePlan.getPartnerNo();
		String agentType = nlifePlan.getAgentType();
		if("3".equals(agentType) || "4".equals(agentType)&&!"1".equals(channelFlag)){
			if("1".equals(state)){
				if(agentType.equals(oldAgentType) && partnerNo.equals(oldPartnerNo)){
					List<Map> list = agentInfoRelaDao.queryAgentInfoByInsuPlanNo(oldPlanNo);
					if(list==null||list.isEmpty()){
						return Result.error("原方案未配置代理信息,该方案不能置为有效");
					}else{
						isCopyTradAgentInfoRela = true;
					}
				}else{
					return Result.error("产品销售类型更改或合作伙伴更改,该方案不能置为有效");
				}
			}
		}
		String planNo ="";
		if(nlifePlan.getIsProprod()){
			planNo = nlifePlanDao.queryNextPlanNo("CIC"+nlifeProd.getCoreProdCode());
		}else{
			planNo = nlifePlanDao.queryNextPlanNo("ZHA");
		}
		nlifePlan.setPlanNo(planNo);
		boolean flag = nlifePlanDao.add(nlifePlan);
		
		if(isCopyTradAgentInfoRela){
			agentInfoRelaDao.copyTradAgentInfoRela(planNo, oldPlanNo);
		}
		
		//清除缓存
		//gatewayClearCacheManager.clearNlifeCacheInfoManager();
//		channelInfoConfigService.clearAllCacheByChannelCode(nlifePlan.getPartnerNo());
		
		if(flag){
			logger.info("==========================添加投保方案成功=============================");

			//根据方案对应的产品的产品类型，查询相应方案组信息,将该方案和方案组信息维护到方案与方案组关联表
			TradPlanGroup planGroup = new TradPlanGroup();
			planGroup.setProdType(nlifeProd.getProdType());
			planGroup = planGroupDao.queryTradPlanGroupID(planGroup);
			
			//维护方案与方案组关联表
			if(planGroup != null){
				TradInsuPlanGroup group = new TradInsuPlanGroup();
				group.setInsuPlanNumber(nlifePlan.getPlanNo());
				group.setPlanGroupId(StrUtil.getVal(planGroup.getGroupId()));
				group.setRequired("0");
				boolean f = insuPlanGroupService.addTradInsuPlanGroup(group);
				
				if(!f){return Result.error("维护方案与方案组关联出错");}
			}
			Map<String,String> returnMap = new HashMap<String,String>();
			returnMap.put("planNo", planNo);
			returnMap.put("agentType", nlifePlan.getAgentType());
			returnMap.put("agentFeeConfig", nlifePlan.getAgentFeeConfig());
			return Result.successAndData("添加成功",returnMap);
		}else{
			return Result.error("添加失败");
		}
	}
	
	@Override
	public Result updateNlifePlan(NlifePlan nlifePlan, NlifeProd nlifeProd)
			throws Exception {
		//产品销售类型为代理类型
		String planNo = nlifePlan.getPlanNo();
		String state = nlifePlan.getState();
		String agentType = nlifePlan.getAgentType();
		if("3".equals(agentType) || "4".equals(agentType)){
			if("1".equals(state)){
				List<Map> list = agentInfoRelaDao.queryAgentInfoByInsuPlanNo(planNo);
				if(list==null||list.isEmpty()){
					return Result.error("代理信息为空 时不能将方案状态置为有效,请配置代理信息");
				}
			}
		}
		
		boolean flag = nlifePlanDao.update(nlifePlan);
		//清除缓存
		//gatewayClearCacheManager.clearNlifeCacheInfoManager();
//		channelInfoConfigService.clearAllCacheByChannelCode(nlifePlan.getPartnerNo());
		
		if(flag){
			logger.info("==========================更新投保方案成功=============================");
			NlifePlan nlifePlan_current = nlifePlanDao.queryById(planNo);
			//如果此方案修改了产品，则同步更改方案与方案组关联，否则不做修改
			if(!nlifePlan_current.getProdCode().equals(nlifePlan.getProdCode())){
				//根据方案对应的产品的产品类型，查询相应方案组信息,将该方案和方案组信息维护到方案与方案组关联表
				TradPlanGroup planGroup = new TradPlanGroup();
				planGroup.setProdType(nlifeProd.getProdType());
				planGroup = planGroupDao.queryTradPlanGroupID(planGroup);
				
				//维护方案与方案组关联表
				if(planGroup != null){
					TradInsuPlanGroup group = new TradInsuPlanGroup();
					group.setInsuPlanNumber(planNo);
					group.setPlanGroupId(StrUtil.getVal(planGroup.getGroupId()));
					group.setRequired("0");
					boolean f =insuPlanGroupService.updateTradInsuPlanGroup(group);
					
					if(!f){return Result.error("维护方案与方案组关联出错");}
				}
			}
			return Result.success("修改成功");
		}else{
			return Result.error("修改失败");
		}
	}
	
	@Override
	public Page<Map<String, Object>> queryAgentInfoRelaPageByCriteria(
			Page<Map<String, Object>> page, String agentType) throws Exception {
		
		if(agentType.equals("3")){
			page = agentInfoRelaDao.queryAgentInfoRelaWithUserPageByCriteria(page);
		}else if(agentType.equals("4")){
			page = agentInfoRelaDao.queryAgentInfoRelaWithChannelPageByCriteria(page);
		}else if(agentType.equals("5")){
			page.getMap().put("parentChannelCode", null);
			page = agentInfoRelaDao.queryAgentInfoRelaWithCombinedPageByCriteria(page);
		}else if(agentType.equals("6")){
			page = coinFeeConfigDao.queryCoinsByPage(page);
		}else if(agentType.equals("7")){
			page = agentInfoRelaDao.queryAgentInfoRelaWithUserPageByCriteria(page);
		}
		return page;
	}

	@Override
	public Page<Map<String, Object>> queryAgentInfoPageByCriteria(
			Page<Map<String, Object>> page, String agentType) throws Exception {
		
		if(agentType.equals("3")){
			page = agentInfoDao.queryAgentInfoWithUserPageByCriteria(page);
		}else if(agentType.equals("4")){
			page = agentInfoDao.queryAgentInfoWithChannelPageByCriteria(page);
		}else if(agentType.equals("5")){
			page = agentInfoDao.queryAgentInfoWithCombinedPageByCriteria1(page);
		}else if(agentType.equals("7")){
			page = agentInfoDao.queryAgentInfoWithUserPageByCriteria(page);
		}
		return page;
	}

	@Override
	public Result updateAgentInfoRela(String agentType,List<String> list,Long userid, String planNo,
		String agentInfoListStr) throws Exception {
		//1、合作伙伴代理3、个人代理4、总对总代理5、联合代理
		//创建一个JsonParser
		JsonParser parser = new JsonParser();
		//通过JsonParser对象可以把json格式的字符串解析成一个JsonElement对象
		JsonElement jsonElement = parser.parse(agentInfoListStr);
		//把JsonElement对象转换成JsonArray
		JsonArray jsonArray = null;
		if(jsonElement.isJsonArray()){
			jsonArray = jsonElement.getAsJsonArray();
		}
		/**广东代理信息是否关联费用跟单*/
		if(list!=null&&list.size()>0){
			Map<String , Object> map=new HashMap<String, Object>();
			map.put("ids", list);
			List<TradAgentInfo> agentInfo= agentInfoDao.isExtTradPlanSale(map);
			if("3".equals(agentType)){
				StringBuffer errMsg=new StringBuffer("广东销售未配置用户名分别为：");
				if(agentInfo!=null&&agentInfo.size()>0){
					for (TradAgentInfo msg : agentInfo) {
						errMsg.append(msg.getUserCode()+",");
					}
					return Result.error(errMsg.toString().substring(0,errMsg.toString().length()-1));
				}	
			}else if("4".equals(agentType)){
				StringBuffer errMsg=new StringBuffer("广东销售未配置网点名称分别为：");
				if(agentInfo!=null&&agentInfo.size()>0){
					for (TradAgentInfo msg : agentInfo) {
						errMsg.append(msg.getSubChannelCode()+",");
					}
					return Result.error(errMsg.toString().substring(0,errMsg.toString().length()-1));
				}	
			}else if("5".equals(agentType)){
				StringBuffer errMsg=new StringBuffer("广东销售未配置业务员代码、代理人代码、代理人协议号分别为：");
				if(agentInfo!=null&&agentInfo.size()>0){
					for (TradAgentInfo msg : agentInfo) {
						errMsg.append((msg.getEmpNo()+'-'+msg.getAgentNo()+"-"+msg.getProtocolNo()+",").replace("null", "未配置"));
					}
					return Result.error(errMsg.toString().substring(0,errMsg.toString().length()-1));
				}	
			}
		}
		StringBuilder ids = new StringBuilder();
		String idStr = "";
		for (JsonElement je : jsonArray) {
			if(je.getAsJsonObject().get("id")!=null){
				String id =je.getAsJsonObject().get("id").getAsString();
				ids.append(id);
				ids.append(",");
			}
		}
		if(ids.length() > 0){
			idStr=ids.substring(0, ids.length()-1);
		}
		
		agentInfoRelaDao.delTradAgentInfoRelaByInsuplannoAndAgentIds(planNo, idStr);
		
		boolean flag = false;
		for (JsonElement je : jsonArray) {
			String id ="";
			if(je.getAsJsonObject().get("id")!=null){
				id =je.getAsJsonObject().get("id").getAsString();
			}
			String commRate=je.getAsJsonObject().get("commrate").getAsString();
			String market=je.getAsJsonObject().get("market").getAsString();
			String business=je.getAsJsonObject().get("business").getAsString();
			if(StrUtil.isNotEmpty(id)){
				TradAgentInfoRela agentInfoRela =new TradAgentInfoRela();
				agentInfoRela.setAgentInfoId(Long.valueOf(id));
				agentInfoRela.setInsuPlanNo(planNo);
				if(StrUtil.isNotEmpty(commRate)){
					BigDecimal bigDecimal = new BigDecimal(commRate);
					bigDecimal = bigDecimal.setScale(6, BigDecimal.ROUND_HALF_UP); 
					agentInfoRela.setCommRate(bigDecimal);
				}
				if(StrUtil.isNotEmpty(market)){
					BigDecimal bigDecimal = new BigDecimal(market);
					bigDecimal = bigDecimal.setScale(6, BigDecimal.ROUND_HALF_UP); 
					agentInfoRela.setMarket(bigDecimal);
				}
				if(StrUtil.isNotEmpty(business)){
					BigDecimal bigDecimal = new BigDecimal(business);
					bigDecimal = bigDecimal.setScale(6, BigDecimal.ROUND_HALF_UP); 
					agentInfoRela.setBusiness(bigDecimal);
				}
				agentInfoRela.setOperTime(new Date());
				agentInfoRela.setOperUser(userid);
				flag = agentInfoRelaDao.addOrUpdateTradAgentInfoRela(agentInfoRela);
			}
		}
		
		if(flag){
			//清除缓存
			//gatewayClearCacheManager.clearNlifeCacheInfoManager();
			return Result.success("更新成功");
		}
		return Result.error("更新失败");
	}

	@Override
	public List<NlifePlan> queryPartnerInfoByProdCode(String prodCode) throws Exception {
		return nlifePlanDao.queryPartnerInfoByProdCode(prodCode);
	}

	@Override
	public List<Map<String, Object>> impNlifePlan(Map<String, Object> map)
			throws Exception {
		return nlifePlanDao.impNlifePlan(map);
	}

	@Override
	public  List<Map<String, Object>> impNlifeRela(Map<String, Object> map)
			throws Exception {
		return agentInfoRelaDao.impNlifeRela(map);
	}

	@Override
	public  List<Map<String, Object>> impNlifeInfo(Map<String, Object> map)
			throws Exception {
		// TODO Auto-generated method stub
		return channelInfoDao.impNlifeInfo(map);
	}

	@Override
	public List<TradAgentInfo> searchTradAgentInfosByplanCode(
			Map<String, Object> maps) throws Exception {
		// TODO Auto-generated method stub
		return nlifePlanDao.searchTradAgentInfosByplanCode(maps);
	}

	@Override
	public List<TradAgentInfoRela> searchTradAgentInfoRelasByplanCode(
			Map<String, Object> maps) throws Exception {
		// TODO Auto-generated method stub
		return nlifePlanDao.searchTradAgentInfoRelasByplanCode(maps);
	}

	@Override
	public Page<CoreDept> queryDeptPageByCriteria1(Page<CoreDept> page,String deptCode)
			throws Exception {
		return coreDeptDao.queryCoreDeptPage2(page, deptCode);
	}

	@Override
	public Page<Map<String, Object>> queryAgentInfoZon4PageByCriteria(
			Page<Map<String, Object>> page) throws Exception {
		return agentInfoRelaDao.queryZonAgentInfoRelaWithPageByCriteria(page);
	}

	@Override
	public Boolean delZonTradInfo(Map<String, Object> map) throws Exception {
			return agentInfoRelaDao.delZonTradInfo(map);
	}

	@Override
	public Result addZonTradInfo(List<TradAgentInfoRela> list,Map<String, Object> map,boolean isTradSale)
			throws Exception {
		/**判断广东机构是否都已配置跟单信息*/
		if(isTradSale){
			List<TradAgentInfo> agentInfos=	agentInfoDao.isExtZonTradPlanSale4(map);
			StringBuffer errMsg=new StringBuffer("广东机构存在未配置费用跟单信息，网点代码分别为: ");
			if(agentInfos!=null&&agentInfos.size()>0){
				for (int i = 0; i < agentInfos.size(); i++) {
					errMsg.append(agentInfos.get(i).getSubChannelCode()+",");
				}
				return Result.error(errMsg.toString().substring(0,errMsg.toString().length()-1));
			}
		}
		agentInfoRelaDao.delZonTradInfo(map);
		agentInfoRelaDao.addZonTradInfo(list);
		return Result.success("配置成功");
	}

	@Override
	public Page<GatewayChannelInfo> queryChannelInfoPageByCriteria1(
			Page<GatewayChannelInfo> page) throws Exception {
			page = channelInfoDao.getListPlanByDept(page);
			return page;
	}

	@Override
	public Page<Map<String, Object>> queryAgentInfoZon5PageByCriteria(
			Page<Map<String, Object>> page) throws Exception {
		return agentInfoRelaDao.queryZonAgentInfoRelaWithPageByParam(page);
	}

	public Result addZonTradInfo5(List<TradAgentInfoRela> list,
			Map<String, Object> map, boolean isTradSale) throws Exception {
		/**判断广东机构是否都已配置跟单信息*/
/*		if(isTradSale){
			List<TradAgentInfo> agentInfos=	agentInfoDao.isExtZonTradPlanSale5(map);
			StringBuffer errMsg=new StringBuffer("广东机构存在未配置费用跟单信息，网点代码分别为: ");
			if(agentInfos!=null&&agentInfos.size()>0){
				for (int i = 0; i < agentInfos.size(); i++) {
					errMsg.append(agentInfos.get(i).getSubChannelCode()+",");
				}
				return Result.error(errMsg.toString().substring(0,errMsg.toString().length()-1));
			}
		}*/
		agentInfoRelaDao.delZonTradInfo5(map);
		agentInfoRelaDao.addZonTradInfo5(list);
		return Result.success("配置成功");
	}

	@Override
	public Boolean delZonTradInfo5(Map<String, Object> map) throws Exception {
		return agentInfoRelaDao.delZonTradInfo5(map);
	}

	@Override
	public Page<Map<String, Object>> loadNlifeHealthInform(
			Page<Map<String, Object>> page) throws Exception {
		
		
		page = nlifePlanDao.queryNlifeHealthInformPageByCriteria(page);

		return page;
	}

	@Override
	public boolean isHealthInformExist(String coreProdCode) throws Exception {
		// TODO Auto-generated method stub
		return nlifePlanDao.isHealthInformExist(coreProdCode);
	}
	
	@Override
	public List<InputStream> getFileInputStream(MultipartFile[] myfiles , String coreProdCode , String healthInformName) throws Exception {
		List<InputStream> inputStreams=new ArrayList<InputStream>();
		try {
			for(MultipartFile file : myfiles){
				//获取文件名
				String fileNameStr = file.getOriginalFilename();
				int lastDotIndex = fileNameStr.lastIndexOf(".");
				//获取文件后缀名
				String extName = fileNameStr.substring(lastDotIndex+1,fileNameStr.length());
				if(-1==lastDotIndex){
					throw new AppException("请选择扩展名为.doc 或 .docx 的文件上传");
				}else{
					
					if(!"doc".equals(extName.toLowerCase()) && !"docx".equals(extName.toLowerCase())){
						throw new AppException("请选择扩展名为.doc 或 .docx 的文件上传");
					}
				}
				if (file.isEmpty()) {
					throw new AppException("上传失败，上传文件不能为空！");
				} else {
					//获取文件全名
					String fileName =  file.getOriginalFilename();
					InputStream in = file.getInputStream();
					
					//判断走哪个逻辑 
					if("doc".equals(extName.toLowerCase())){
						DocToHtml.dox(file.getOriginalFilename().split("\\.")[0], file.getOriginalFilename().split("\\.")[1], "index");
					}else if("docx".equals(extName.toLowerCase())){
						String content = DocToHtml.docx(in, "index");
						
						//存数据库
						Map<String,Object> map = new HashMap<String, Object>();
						map.put("content", content);
						map.put("coreProdCode", "CORE" + coreProdCode);
						map.put("healthInformName", healthInformName);
						//先删除已存在的
						nlifePlanDao.delNlifeHealthInform((String) map.get("coreProdCode"));
						nlifePlanDao.insertNewHealthInform(map);
						/*ruleInfoDao.insertNewRiskContent(map);*/
					}
					InputStream inputStream = file.getInputStream();
					inputStreams.add(inputStream);
				}
			}
		} catch (IOException e) {
			throw new AppException("上传错误!请稍后重试");
		}
		return inputStreams;
	}

	@Override
	/*删除已有健康告知*/
	public void delNlifeHealthInform(String id) throws Exception {
		nlifePlanDao.delNlifeHealthInform(id);
	}

	@Override
	public NlifeCoreRisk queryMainRiskOrFirstRisk(String prodCode) throws Exception {
		int count = nlifeRiskDao.queryMainRiskCount(prodCode);
		if(count > 1){
			NlifeRisk nl=nlifeRiskDao.queryFirstRisk(prodCode);
			return iNlifeCoreRiskDao.queryCoreRiskById(nl.getCoreRiskCode());
		} else {
			List<NlifeRisk> list = nlifeRiskDao.queryMainRisk(prodCode);
			if(list.size() == 0 ){
				NlifeRisk fnl=nlifeRiskDao.queryFirstRisk(prodCode);
				return iNlifeCoreRiskDao.queryCoreRiskById(fnl.getCoreRiskCode());
			} else{
				NlifeRisk nl= list.get(0);
				return iNlifeCoreRiskDao.queryCoreRiskById(nl.getCoreRiskCode());
			}
		}
	}

	@Override
	public List<Map<String, Object>> queryUpdateInfomation(String prodCode) throws Exception {
		List<Map<String, Object>> rs = nlifeCoreProdDao.queryUpdateInfomation(prodCode);
		return rs;
	}
}
